package com.brotherly.framework.transaction;

import com.brotherly.util.Factory;

public class TransactionTask implements PacemakerWatcher, Factory<TransactionTask>, Runnable
{
    protected Pacemaker pacemaker;
    protected Driver driver;
    protected Party party;
    protected Transaction transaction;
    protected boolean actived;

    public TransactionTask()
    {}

    public void active(Transaction transaction, PacemakerFactory pacemakerFactory, DriverFactory driverFactory)
    {
        pacemaker = null;
        driver = null;
        this.transaction = transaction;

        if (pacemakerFactory != null)
        {
            pacemaker = pacemakerFactory.createInstance();
        }

        if (driverFactory != null)
        {
            driver = driverFactory.createInstance();
        }

        party = transaction.getParty();

        if (party != null)
        {
            party.onActive(transaction);
        }

        if (driver != null)
        {
            driver.active(transaction);
        }

        if (pacemaker != null)
        {
            pacemaker.active(transaction, this);
        }

        actived = true;
    }

    public synchronized void inactive()
    {
        actived = false;

        if (pacemaker != null)
        {
            pacemaker.inactive(transaction);
        }

        if (driver != null)
        {
            driver.inactive(transaction);
        }

        if (party != null)
        {
            party.onInactive(transaction);
        }
    }

    @Override
    public synchronized void trigger()
    {
        if (actived)
        {
            TransactionServiceHost.getThreadPool().execute(this);
        }
    }

    @Override
    public TransactionTask newInstance()
    {
        return new TransactionTask();
    }

    @Override
    public synchronized void run()
    {
        if (!actived)
            return;

        try
        {
            byte[] readyData = null;
            byte[] data = null;

            if (party != null)
                readyData = party.onReady(transaction);

            if (driver != null)
                data = driver.deal(transaction, readyData);

            if (party != null)
                party.onData(data);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    @Override
    public void init(TransactionTask element)
    {

    }

    @Override
    public void uninit(TransactionTask element)
    {

    }
}
